package ofc;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;

import jofc2.model.Chart;
import jofc2.model.Text;
import jofc2.model.axis.XAxis;
import jofc2.model.axis.XAxisLabels;
import jofc2.model.axis.YAxis;
import jofc2.model.elements.Element;
import jofc2.model.elements.LineChart;

public abstract class ChartCreator {

	//此部分由于具体的曲线型，柱状等图形的设置会有不同，故用protected
    protected static String     BACKGROUND_COLOR       = "#FFFFFF";
    //告警上限颜色
	public static final String  MAX_ALARM_LIMIT_COLOR     = "#FF0000";
	//告警下限颜色
    public static final String  MIN_ALARM_LIMIT_COLOR     = "#0000FF";
    //图形中的线，饼等的颜色
    protected static String  CHART_COLOR         = "#00FF00";
    protected static String        DATE_FORMATTER           = "yy-MM-dd\nHH:mm:ss";
    protected static final String  STRING_DATE_FORMATTER    = "yyyy-MM-dd HH:mm:ss";          //格式也很重要，开始搞成-一直不行
    protected static String        TIME_ZONE               = "GMT+8";

    protected Chart                chart;
    protected Map<String, Element> elements                 = new HashMap<String, Element>(2);
    //xy轴
    protected XAxis                xAxis                    = new XAxis();
    protected YAxis                yAxis                    = new YAxis();
    
    protected LineChart            maxAlarmLineChart;
    protected LineChart            minAlarmLineChart;

    private int                  valueCount               = 20;
    protected long                 index                    = 0;
    private int                  labelSplit               = 5;

    protected Text                 title                    = new Text();
    protected Text                 xLegend                  = new Text();
	protected Text                 yLegend                  = new Text();

    public ChartCreator() {
    }

    public int getValueCount() {
		return valueCount;
	}

	public void setValueCount(int valueCount) {
		this.valueCount = valueCount;
	}

	public void init(String title) {
        init(title, valueCount);
    }

    //具体图表不设置时使用的默认设置
    public void init(String title, int valueCount) {
        //供显示的值个数
    	this.valueCount = valueCount;
        //初始化图表
        chart = new Chart();
        //设置标题
        this.title.setText(title);
        chart.setTitle(this.title);
        //设置背景颜色
        chart.setBackgroundColour(BACKGROUND_COLOR);     
        //增加默认的Y轴坐标
        yAxis.setRange(OfcConsts.DEFAULT_Y_AXIS_MIN_VALUE, OfcConsts.DEFAULT_Y_AXIS_MAX_VALUE, OfcConsts.DEFAULT_Y_AXIS_STEP);
        //设置默认的xy轴
        chart.setXAxis(xAxis);
        chart.setYAxis(yAxis);
        
        //设置X轴描叙，有错误，设置了显示不正常，故注释
        //chart.setXLegend(xLegend);
        //设置Y轴描叙
        //chart.setYLegend(yLegend);
    }

    /**
     * 设置标题
     * 
     * 
     * @param title
     */
    public void setTitle(String text) {
        this.title.setText(text);
    }
    
    /**
     * 获取标题
     * 
     * 
     * @param title
     */
    public void getTitle() {
        this.title.getText();
    }
    
    public int getLabelSplit() {
		return labelSplit;
	}

	public void setLabelSplit(int labelSplit) {
		this.labelSplit = labelSplit;
	}
    
    /**
     * 设置标题</br>
     * 问题：设置之后无法解析
     * 
     * @param title
     */
    @Deprecated
    public void setXLegend(String text) {
        this.xLegend.setText(text);
    }
    
    /**
     * 设置标题</br>
     * 问题：设置之后无法解析
     * 
     * @param title
     */
    @Deprecated
    public void setYLegend(String text) {
        this.yLegend.setText(text);
    }

    /**
     * 设置Y轴坐标上下限
     * 
     * @param maxLimit
     * @param minLimit
     * @param step
     */
    public void setYAxisLimit(int minLimit, int maxLimit, int step) {
        yAxis.setRange(minLimit, maxLimit, step);
    }

    /**
     * 设置告警量的告警上限（不设置则不显示）
     * 
     * @param maxAlarmLimit
     * @param minAlarmLimit
     * @param color
     */
    public void setMaxAlarmLimit(int maxAlarmLimit,int valueCount) {
        if (maxAlarmLineChart == null) {
            maxAlarmLineChart = new LineChart();
            maxAlarmLineChart.setText("告警上限");
            maxAlarmLineChart.setFontSize(OfcConsts.DEFAULT_FONT_SIZE);
            maxAlarmLineChart.setAlpha(0.1f);
            chart.addElements(maxAlarmLineChart);
        }
        maxAlarmLineChart.setColour(MAX_ALARM_LIMIT_COLOR);

        List<Object> values = maxAlarmLineChart.getValues();
        values.clear();
        while (values.size() < valueCount) {
            values.add(maxAlarmLimit);
        }
    }

    /**
     * 删除告警量的告警上限
     */
    public void removeMaxAlarmLimit() {
        if (maxAlarmLineChart != null) {
            chart.removeElement(maxAlarmLineChart);
        }
        maxAlarmLineChart = null;
    }

    /**
     * 设置告警量的告警下限（不设置则不显示）
     * 
     * @param minAlarmLimit
     * @param color
     */
    public void setMinAlarmLimit(int minAlarmLimit,int valueCount) {
        if (minAlarmLineChart == null) {
            minAlarmLineChart = new LineChart();
            minAlarmLineChart.setText("告警下限");
            minAlarmLineChart.setFontSize(OfcConsts.DEFAULT_FONT_SIZE);
            minAlarmLineChart.setAlpha(0.1f);
            chart.addElements(minAlarmLineChart);
        }
        minAlarmLineChart.setColour(MIN_ALARM_LIMIT_COLOR);

        List<Object> values = minAlarmLineChart.getValues();
        values.clear();
        while (values.size() < valueCount) {
            values.add(minAlarmLimit);
        }
    }

    /**
     * 删除告警量的告警下限
     */
    public void removeMinAlarmLimit() {
        if (minAlarmLineChart != null) {
            chart.removeElement(minAlarmLineChart);
        }
        minAlarmLineChart = null;
    }

    /**
     * 设置告警量的告警上下限（不设置则不显示）
     * 
     * @param maxAlarmLimit
     * @param minAlarmLimit
     */
    public void setAlarmLimit(int minAlarmLimit, int maxAlarmLimit,int valueCount) {
        setMinAlarmLimit(minAlarmLimit,valueCount);
        setMaxAlarmLimit(maxAlarmLimit,valueCount);
    }

    /**
     * 格式化时间显示
     * 
     * @param date
     * @param format
     * @return
     */
    public static String dateToStr(Date date, String format) {
        if (date == null) {
            date = new Date();
        }
        if (format == null) {
            format = DATE_FORMATTER;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        sdf.setTimeZone(TimeZone.getTimeZone(TIME_ZONE));
        return sdf.format(date);
    }

    /**
     * 格式化时间显示
     * 
     * @return
     */
    public static String dateToStr() {
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMATTER);
        sdf.setTimeZone(TimeZone.getTimeZone(TIME_ZONE));
        return sdf.format(new Date());
    }

    

    /**
     * 获取图标的JSON表示串
     * 
     * @return
     */
    public String getChart() {
        return chart.toString();
    }

    /**
     * 是否有图表
     * 
     * @return
     */
    public boolean isEmpty() {
        return elements.isEmpty();
    }

    /**
     * 去掉告警量的告警上下限
     */
    protected void removeAlarmLimit() {
        removeMaxAlarmLimit();
        removeMinAlarmLimit();
    }

    /**
     * 去掉指定的图表
     * 
     * @param element
     */
    protected void removeElement(Element element) {
        chart.removeElement(element);
    }

    /**
     * 去掉指定的图表
     * 
     * @param element
     */
    protected void removeElement(String devId) {
        Element element = elements.get(devId);
        if (element != null) {
            removeElement(element);
        }
    }

    /**
     * 去掉所有显示的图表
     */
    protected void removeAllElement() {
        Element element = null;
        for (String key : elements.keySet()) {
            element = elements.get(key);
            if (element != null) {
                chart.removeElement(element);
            }
        }
    }
    
    /**
     * 清理X轴显示
     */
    protected void clearXAxis() {
        if (xAxis.getLabels().getLabels() != null) {
            chart.getXAxis().getLabels().getLabels().clear();
            index = 0;
        }
    }

    /**
     * 清理Y轴显示
     */
    protected void clearYAxis() {
        chart.getYAxis().getLabels().getLabels().clear();
    }
    
    public void clearHistory(String devId) {
        Element element = elements.get(devId);
        if (element != null) {
            if (element instanceof LineChart) {
                ((LineChart)element).getValues().clear();
            }
        }
        clearXAxis();
    }

    /**
     * 增加一个监控设备（实际增加一条曲线）。需要子类实现
     * 
     * @param deviceId
     * @param deviceName
     * @param color
     */
    public Element addElement(String deviceId, String deviceName) {
        return addLineChart(deviceId, deviceName, CHART_COLOR);
    }

    /**
     * 增加一个监控设备（实际增加一条曲线）。需要子类实现
     * 
     * @param deviceId
     * @param deviceName
     * @param color
     */
    public Element addLineChart(String deviceId, String deviceName, String color) {
        LineChart lineChart = new LineChart();
        if (color == null || !"".equals(color)) {
            color = CHART_COLOR;
        }
        lineChart.setColour(color);
        if (deviceName != null && !"".equals(deviceName)) {
            lineChart.setText(deviceName);
        }
        lineChart.setFontSize(OfcConsts.DEFAULT_FONT_SIZE);
        chart.addElements(lineChart);
        elements.put(deviceId, lineChart);

        return lineChart;
    }

    /**
     * 增加指定监控设备的X轴数据。需要子类实现
     * 
     * @param deviceId
     * @param value
     */
    public void addValue(String deviceId, Number value) {
        List<Object> values = elements.get(deviceId).getValues();
        if (values.size() >= valueCount) {
            values.remove(0);
        }
        if(index%2==0){
        values.add(value);
        }
        else{
        values.add(60);
        }
    }

    /**
     * 增加指定监控设备的X轴标签。需要子类实现
     * 
     * @param deviceId
     * @param Label
     */
    public void addLabel(String deviceId, String label) {
        boolean isShowLabel = isShowLabel();
        if (isShowLabel && (label == null || label.equals(""))) {
            label = dateToStr();
        }

        XAxisLabels xLabel = xAxis.getLabels();
        if (xLabel.getLabels() == null) {
            xLabel.addLabels(label);
        } else {
            List<Object> labels = xLabel.getLabels();
            if (labels.size() >= valueCount) {
                labels.remove(0);
            }

            if (isShowLabel) {
                labels.add(label);
            } else {
                labels.add("");
            }
        }
    }

    /**
     * 是否显示当前索引标签
     * 
     * @return
     */
    public boolean isShowLabel() {
        return index++ % labelSplit == 0;
    }
    
    /**
     * 返回纵坐标值间距
     * 
     * @param screennum
     */
    @SuppressWarnings("finally")
	public int getStep(String screennum) {
        try{
        	int screen=Integer.parseInt(screennum)+1;
        	if(0<screen&&screen<5){
        		return 20;
        	}
        	else if(5<=screen&&screen<=9){
        		return 40;
        	}
        	else
        		return 50;
        }
        finally{
        	return 20;
        }
    }
    
    public List<Element> getElements(){
    	return (List<Element>) chart.getElements();
    }
    
    /**
     * 仅获取图表改变的值，减少网络传输
     * 
     * @return
     */
    public abstract String getChartChange(String deviceId);
}